js遗漏知识点

undefined 与 null

  • 区别
    在使用var声明变量但未对其初始化时,变量的指为undefined;
    null 指表示一个空对象指针。
1
2
typeof(undefined);      //undefined
typeof(null); //object
  • 联系
    undefined 值派生自 null值
    1
    alert(null == undefined);       //true

作用域和作用域链

  • 作用域
    js中,作用域只有两个:全局作用域和函数作用域,无块级作用域。
  • 作用域链
    当代码在一个环境中执行时,会创建变量的作用域链。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的==有序访问==。作用域链的前端,始终都是当前执行的代码所在环境的变量对象,下一个变量对象来自包含(外部)环境,在下一个对象则来自下一个包含环境,这样,一直延续到全局环境。全局执行环境的变量对象始终都是作用域链中的最后一个对象

this

this 是函数内部的对象,引用的是函数执行环境的对象,当在网页的全局作用域中调用函数时,this对象引用的就是window,当函数作为某个对象的方法调用时,this等于那个对象

1
2
3
4
5
6
7
8
9
var name = "name";
var object = {
name : "object",
getName : function() {
return this.name
}
}

object.getName(); //object

apply call bind

每个函数都包含两个非继承而来的方法:apply() 和 call()。它们的用途都是在特定的作用域种调用函数,实际上等于设置==函数体内的this对象==的值

  • apply
    apply()方法接收两个参数——运行函数的作用域和参数数组,其中,第二个参数可以是Array的实例,也可以是arguments对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function sum(num1, num2) {
return num1 + num2;
}

function callSum1(num1, num2) {
return sum.apply(this, arguments);
}

function callSum2(num1, num2) {
return sum.apply(this, [num1, num2]);
}

console.log(callSum1(10, 10)); //20
console.log(callSum2(10, 10)); //20
  • call
    call() 与 apply() 方法的作用相同,不同的是调用参数,call() 也接收两个参数,第一个参数为this指没有变化,变化的是其余参数都直接传递给函数。
1
2
3
4
5
6
7
8
9
function sum(num1, num2) {
return num1 + num2;
}

function callSum(num1, num2) {
return sum.call(this, num1, num2);
}

console.log(callSum(10, 10)); //20

call() 与 apply() 能==扩充函数作用域==

1
2
3
4
5
6
7
8
9
10
11
12
window.color = "red";
var o = {color : "blue"};

function getColor() {
return this.color;
}

getColor(); //red

getColor.call(this); //red
getColor.call(window); //red
getColor.call(o); //blue

使用call() 与 apply() 扩充作用域,对象不需与方法有任何耦合的关系

  • bind
    bind() 会创建一个函数的实例,其this值会被绑定到传给bind()函数的值。
1
2
3
4
5
6
7
8
window.color = "red";
var o = {color : "blue"};
function getColor() {
return this.color;
}

var bindColor = getColor.bind(o);
bindColor(); //blue

forEach map reduce

该方法为==数组方法==。其中forEach() 和 map() 为迭代方法,接收三个参数:数组项的值、该项在数组中的位置和数组对象本身。

  • forEach()
    对数组中的每一项运行给定的函数,==无返回值==,本质上与使用for循环迭代数组一样
1
2
3
4
5
var num = [1, 2, 3, 4, 5];

num.forEach(function(item, index, array) {
console.log(item); //operations
})
  • map()
    对数组中的每一项运行给定函数,==返回每次函数调用结果组成的数组==。
1
2
3
4
5
6
7
var num = [1, 2, 3, 4, 5];

var mapResult = num.map(function(item, index, array) {
return item * 2;
});

console.log(mapResult); //[2, 4, 6, 8, 10]
  • reduce()
    reduce() 为归并数组的方法,从数组的第一项开始,逐个遍历到最后,然后构建一个最终返回的值。该方法接收四个参数:前一个值、当前值、项的索引和数组对象。函数返回的任何值都会作为第一个参数自动传递给下一项
1
2
3
4
5
6
var num = [1, 2, 3, 4, 5];
var sum = num.reduce(function(prev, cur, index, array){
return prev + cur;
});

console.log(sum);

函数柯里化

函数柯里化用于创建已经设置好了一个或多个参数的函数,基本方法是使用闭包返回一个函数,当函数被调用时,返回的函数还需设置一些传入参数。

柯里化动态创建步骤:调用另一个函数并为它传入要柯里化的函数和必要参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function curry(fn) {
var args = Array.prototype.slice.call(arguments, 1);
return function() {
var innerArgs = Array.prototype.slice.call(arguments);
var finalArgs = args.concat(innerArgs);
return fn.apply(null, finalArgs);
}
}

function sum(num1, num2) {
return num1 + num2;
}

var currySum = curry(add, 5);
console.log(currySum(3)); //8